package at.knorre.swipebeam;

import android.app.Service;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.renderscript.RenderScript;
import android.renderscript.RenderScriptGL;
import android.service.wallpaper.WallpaperService;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.WindowManager;

public class SwipeBeamWallpaperService extends WallpaperService {

	@Override
	public Engine onCreateEngine() {
		return new RenderScriptEngine();
	}

	private class RenderScriptEngine extends Engine implements OnSharedPreferenceChangeListener {
		private RenderScriptGL mRenderScript = null;
		private SwipeBeamRS mWallpaperRS = null;
		private int mDensityDPI;
		private SharedPreferences mSharedPreferences;

		@Override
		public void onCreate(SurfaceHolder surfaceHolder) {
			super.onCreate(surfaceHolder);
			setTouchEventsEnabled(true);
			surfaceHolder.setSizeFromLayout();
			surfaceHolder.setFormat(PixelFormat.OPAQUE);

			DisplayMetrics metrics = new DisplayMetrics();
			((WindowManager) getApplication().getSystemService(Service.WINDOW_SERVICE))
					.getDefaultDisplay().getMetrics(metrics);
			mDensityDPI = metrics.densityDpi;

			mSharedPreferences = getSharedPreferences(SwipeBeamPreferences.SHARED_PREFS_NAME,
					MODE_PRIVATE);
			mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
		}

		@Override
		public void onDestroy() {
			super.onDestroy();
			destroyRenderer();
		}

		public void destroyRenderer() {
			if (mWallpaperRS != null) {
				mWallpaperRS.stop();
				mWallpaperRS = null;
			}

			if (mRenderScript != null) {
				mRenderScript.setSurface(null, 0, 0);
				mRenderScript.destroy();
				mRenderScript = null;
			}
		}

		@Override
		public void onSurfaceCreated(SurfaceHolder surfaceHolder) {
			super.onSurfaceCreated(surfaceHolder);

			RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
			mRenderScript = new RenderScriptGL(SwipeBeamWallpaperService.this, sc);
			mRenderScript.setPriority(RenderScript.Priority.NORMAL);
		}

		@Override
		public void onSurfaceDestroyed(SurfaceHolder surfaceHolder) {
			super.onSurfaceDestroyed(surfaceHolder);
			destroyRenderer();
		}

		@Override
		public void onSurfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
			super.onSurfaceChanged(surfaceHolder, format, width, height);

			if (mRenderScript != null) {
				mRenderScript.setSurface(surfaceHolder, width, height);
			}

			if (mWallpaperRS == null) {

				mWallpaperRS = new SwipeBeamRS();
				mWallpaperRS.init(mDensityDPI, mRenderScript, getResources(), width, height,
						mSharedPreferences.getString(SwipeBeamPreferences.PREF_COLOR_SCHEME,
								getResources().getString(R.string.pref_colorScheme_default)));
				mWallpaperRS.start();
			}

			mWallpaperRS.resize(width, height);
		}

		@Override
		public Bundle onCommand(String action, int x, int y, int z, Bundle extras,
				boolean resultRequested) {
			return null;
		}

		@Override
		public void onVisibilityChanged(boolean visible) {
			super.onVisibilityChanged(visible);
			if (mWallpaperRS != null) {
				if (visible) {
					mWallpaperRS.start();
				} else {
					mWallpaperRS.stop();
				}
			}
		}

		@Override
		public void onTouchEvent(MotionEvent event) {
			super.onTouchEvent(event);

			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				mWallpaperRS.setTouch(true);
			} else if (event.getAction() == MotionEvent.ACTION_CANCEL
					|| event.getAction() == MotionEvent.ACTION_UP) {
				mWallpaperRS.setTouch(false);
			}
		}

		@Override
		public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
				float yOffsetStep, int xPixelOffset, int yPixelOffset) {
			mWallpaperRS.setOffset(xOffset, yOffset, xPixelOffset, yPixelOffset);
		}

		@Override
		public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
			if (mWallpaperRS == null || !key.equals(SwipeBeamPreferences.PREF_COLOR_SCHEME))
				return;

			mWallpaperRS.stop();
			mWallpaperRS.mInited = false;
			mWallpaperRS.init(mDensityDPI, mRenderScript, getResources(), mWallpaperRS.mWidth,
					mWallpaperRS.mHeight, mSharedPreferences.getString(
							SwipeBeamPreferences.PREF_COLOR_SCHEME,
							getResources().getString(R.string.pref_colorScheme_default)));
			mWallpaperRS.start();
		}

	}

}